﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using Nuwanda.Common;
using Nuwanda.TfsSpotlight.Data;
using StructureMap;

namespace Nuwanda.TfsSpotlight.Views.ChartView
{
    [Author("Bartłomiej Legiędź")]
    [Pluggable("ChartView")]
    public partial class ChartView : BaseUserControl, IChartView
    {
        public IChartPresenter Presenter { get; set; }

        public ChartView()
        {
            InitializeComponent();
        }

        public void SetChartArea(ChartArea chartArea)
        {
            if(this.chart.InvokeRequired)
            {
                this.chart.Invoke(new MethodInvoker(() => this.SetChartArea(chartArea)));
                return;
            }

            this.chart.ChartAreas.Add(chartArea);
            
        }

        public void SetChartTitle(Title title)
        {
            if (this.chart.InvokeRequired)
            {
                this.chart.Invoke(new MethodInvoker(() => this.SetChartTitle(title)));
                return;
            }

            this.chart.Titles.Clear();
            this.chart.Titles.Add(title);
        }

        public void SetWorkItemFields(List<string> fields)
        {
            if (this.kcbFields.InvokeRequired)
            {
                this.kcbFields.Invoke(new MethodInvoker(() => this.SetWorkItemFields(fields)));
                return;
            }

            this.kcbFields.DataSource = fields;
        }

        public void SetChartTypesDataSource(List<string> chartTypes)
        {
            if (this.kcbChartType.InvokeRequired)
            {
                this.kcbChartType.Invoke(new MethodInvoker(() => this.SetChartTypesDataSource(chartTypes)));
                return;
            }

            this.kcbChartType.DataSource = chartTypes;
        }

        public void SetChartOptionsDataSource(ChartOptions options)
        {
            if(this.InvokeRequired)
            {
                this.Invoke(new MethodInvoker(() => this.SetChartOptionsDataSource(options)));
                return;
            }

            this.bsChartOptions.DataSource = options;
        }

        public void SetHeaderTitle(string title)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new MethodInvoker(() => this.SetHeaderTitle(title)));
                return;
            }

            this.khgHeader.ValuesPrimary.Heading = title;
        }

        public void SetHeaderImage(Image image)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new MethodInvoker(() => this.SetHeaderImage(image)));
                return;
            }

            this.khgHeader.ValuesPrimary.Image = image;
        }

        public void DisplayChart(Series series)
        {
            if(this.chart.InvokeRequired)
            {
                this.chart.Invoke(new MethodInvoker(() => this.DisplayChart(series)));
                return;
            }

            this.chart.Series.Clear();
            this.chart.Series.Add(series);
        }

        public void ClearChart()
        {
            if (this.chart.InvokeRequired)
            {
                this.chart.Invoke(new MethodInvoker(() => this.ClearChart()));
                return;
            }

            this.chart.Series.Clear();
            this.chart.Titles.Clear();
        }

        public Image GetImage(ImageFormat format)
        {
            if(this.chart.InvokeRequired)
            {
                return (Image) this.chart.Invoke(new Func<Image>(() => this.GetImage(format)));
            }

            var stream = new MemoryStream();
            this.chart.SaveImage(stream, format);

            return Image.FromStream(stream);
        }

        public void DisableControlPanel()
        {
            if (this.kryptonPanel1.InvokeRequired)
            {
                this.kryptonPanel1.Invoke(new MethodInvoker(() => this.DisableControlPanel()));
                return;
            }

            this.kryptonPanel1.Enabled = false;
        }

        public void EnableControlPanel()
        {
            if (this.kryptonPanel1.InvokeRequired)
            {
                this.kryptonPanel1.Invoke(new MethodInvoker(() => this.EnableControlPanel()));
                return;
            }

            this.kryptonPanel1.Enabled = true;
        }

        public void ShowProgress()
        {
            if (this.pbQueryProgress.InvokeRequired)
            {
                this.pbQueryProgress.Invoke(new MethodInvoker(() => this.ShowProgress()));
                return;
            }

            this.pbQueryProgress.Visible = true;
        }

        public void HideProgress()
        {
            if (this.pbQueryProgress.InvokeRequired)
            {
                this.pbQueryProgress.Invoke(new MethodInvoker(() => this.HideProgress()));
                return;
            }

            this.pbQueryProgress.Visible = false;
        }


        private void WorkItemFieldChangedHandler(object sender, EventArgs e)
        {
            this.Presenter.UpdateChart();
        }

        private void ChartTypeChanhedHandler(object sender, EventArgs e)
        {
            this.kcbChartType.DataBindings[0].WriteValue();
            this.Presenter.UpdateChartStyle();
        }

        private void CopyChartToClipboardHandler(object sender, EventArgs e)
        {
            this.Presenter.HandleCopyChartToClipboard();
        }

        private void SaveChartAsImageHandler(object sender, EventArgs e)
        {
            this.Presenter.HandleSaveChartAsImage();
        }

        private void ShowIn3DChangedHandler(object sender, EventArgs e)
        {
            this.kcbShow3D.DataBindings[0].WriteValue();
            this.Presenter.UpdateChartStyle();
        }

        private void SortByValueCheckedHandler(object sender, EventArgs e)
        {
            this.kcbSortByValueCount.DataBindings[0].WriteValue();
            this.Presenter.UpdateChart();
        }

        public void SelectChartType(string chartType)
        {
            if(this.kcbChartType.InvokeRequired)
            {
                this.kcbChartType.Invoke(new MethodInvoker(() => this.SelectChartType(chartType)));
                return;
            }

            this.kcbChartType.SelectedItem = chartType;
        }
    }
}
